﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using DoeObjects;
using DoeLibsMVC.Security;
using DoeLibsMVC.Models;
using DoeLibsMVC.Filter;

namespace DoeLibsMVC.Controllers.api
{
    public class UserController : BaseApiController
    {

        /// <summary>
        /// returns information about the logged in user
        /// </summary>
        /// <returns></returns>
        [BasicAuthorize]
        public HttpResponseMessage Get()
        {
            return Request.CreateResponse<DoeObjects.User>(HttpStatusCode.OK, (DoeObjects.User)User);
        }

        /// <summary>
        /// returns information about the given user
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [BasicAuthorize(Roles=UserCategoryHelper.STAFF_CATEGORY)]
        public HttpResponseMessage Get(int id)
        {
            DoeObjects.User user = DoeObjects.User.getUserByUserId(id);

            if (user != null)
            {
                return Request.CreateResponse<DoeObjects.User>(HttpStatusCode.OK, user);
            }
            else
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }
        }

		/// <summary>
		/// Search for users using the given search string. Returns the result but without the password and salt in the objects.
		/// </summary>
		/// <param name="searchTerm"></param>
		/// <returns></returns>
		[BasicAuthorize(Roles = UserCategoryHelper.STAFF_CATEGORY)]
		public HttpResponseMessage Get(string searchTerm)
		{
			if (!String.IsNullOrEmpty(searchTerm)) searchTerm = Uri.UnescapeDataString(searchTerm);
			else return Request.CreateResponse(HttpStatusCode.NotFound);
			
			// TODO: Maybe add functionallity to search on categoryid or not.
			List<User> result = DoeObjects.User.getUsersBySearchPhrase(searchTerm, 1);
			if (result.Count == 0) return Request.CreateResponse(HttpStatusCode.NotFound);
			else
			{
				foreach (DoeObjects.User user in result)
				{
					user.Password = "";
					user.Salt = "";
				}
				return Request.CreateResponse<List<DoeObjects.User>>(HttpStatusCode.OK, result);
			}
		}

        ///// <summary>
        ///// Renews the expiration date for the user. Does not work for staff members.
        ///// </summary>
        ///// <param name="id"></param>
        ///// <returns></returns>
        //[BasicAuthorize(Roles = UserCategoryHelper.STAFF_CATEGORY)]
        //public HttpResponseMessage Put(int id)
        //{
        //    DoeObjects.User user = DoeObjects.User.getUserByUserId(id);
        //    if (user == null) return Request.CreateResponse(HttpStatusCode.NotFound);

        //    user.renewExpirationDate();
        //    return Request.CreateResponse(HttpStatusCode.OK);
        //}

        [BasicAuthorize]
        public HttpResponseMessage Put(int id, EditUserModel model)
        {
            if (User.Category.Name == UserCategoryHelper.STAFF_CATEGORY)
            {
                if (string.IsNullOrEmpty(model.Room))
                {
                    ModelState.AddModelError("Room", "The field \"room\" is required");
                }

                if (string.IsNullOrEmpty(model.UniPhone))
                {
                    ModelState.AddModelError("UniPhone", "The field \"phone\" is required");
                }
            }

            if (SecurityHelper.secureString(User.Salt + model.OldPassword) != User.Password)
            {
                ModelState.AddModelError("OldPassword", "The password is incorrect");
            }

            if (model.NewPassword != model.NewPasswordConfirm)
            {
                ModelState.AddModelError("NewPasswordConfirm", "The passwords must match");
            }

            if (ModelState.IsValid)
            {
                DoeObjects.User user = DoeObjects.User.getUserByUserId(User.UserId);
                user.EMail = model.EMail;
                if (!string.IsNullOrEmpty(model.NewPassword))
                {
                    user.Salt = SecurityHelper.generateSalt();
                    user.Password = SecurityHelper.secureString(user.Salt + model.NewPassword);
                }

                if (User.Category.Name == UserCategoryHelper.STAFF_CATEGORY)
                {
                    user.Room = model.Room;
                    user.UniPhone = model.UniPhone;
                }

                if (user.save())
                {
                    return Request.CreateResponse(HttpStatusCode.OK);
                }
                else
                {
                    return Request.CreateResponse(HttpStatusCode.InternalServerError);
                }
            }
            else
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest, FilterHelper.makeErrorsNice(ModelState));
            }
        }

        [BasicAuthorize(Roles = UserCategoryHelper.STAFF_CATEGORY)]
        public HttpResponseMessage Post(int id, string renewExpireDate)
        {
            DoeObjects.User requestingUser = DoeObjects.User.getUserByUserId(id);

            if (requestingUser != null)
            {
                requestingUser.renewExpirationDate();

                Notification notification = new Notification();
                notification.Recipient = requestingUser;
                notification.Sender = User;
                notification.Type = NotificationType.RENEW_EXPIRE_DATE_REQUEST_ALLOWED;
                notification.Message = string.Format("Your account has been extended for another semester");

                if (notification.save())
                {
                    return Request.CreateResponse(HttpStatusCode.OK);
                }
                else
                {
                    return Request.CreateResponse(HttpStatusCode.InternalServerError);
                }
            }
            else
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }
        }

        /// <summary>
        /// method to send a renew expire date request
        /// </summary>
        /// <param name="renewExpireDateRequest"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        [BasicAuthorize(Roles=UserCategoryHelper.STUDENT_CATEGORY)]
        public HttpResponseMessage Post(string renewExpireDateRequest, RenewExpireDateModel model)
        {
            DoeObjects.User recipient = DoeObjects.User.getUserByUserId(model.AcceptorId);

            if (recipient != null)
            {
                Notification notification = new Notification();
                notification.Recipient = recipient;
                notification.Sender = User;
                notification.Type = NotificationType.RENEW_EXPIRE_DATE_REQUEST;
                notification.Message = string.Format("{0} {1} ({2}) asks you for renewing his account for another semester", User.FirstName, User.LastName, User.EMail);

                if (notification.save())
                {
                    return Request.CreateResponse(HttpStatusCode.OK);
                }
                else
                {
                    return Request.CreateResponse(HttpStatusCode.InternalServerError);
                }
            }
            else
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }
        }
    }
}
